package net.csdn.business.mirror.controller;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.common.annotation.Inner;
import net.csdn.business.common.domain.mirror.*;
import net.csdn.business.common.domain.query.mirror.MirrorConfigQuery;
import net.csdn.business.common.domain.query.mirror.MirrorPageQuery;
import net.csdn.business.common.domain.query.mirror.TokenConfigQuery;
import net.csdn.business.common.domain.request.mirror.*;
import net.csdn.business.common.domain.vo.mirror.MirrorConfigVO;
import net.csdn.business.common.domain.vo.mirror.MirrorNameSpaceVO;
import net.csdn.business.common.domain.vo.mirror.ProjectMirrorDataVO;
import net.csdn.business.common.domain.vo.mirror.MirrorProjectPageVO;
import net.csdn.business.common.enums.ResultCodeEnum;
import net.csdn.business.common.exception.BusinessException;
import net.csdn.business.mirror.config.ImportMirrorConfig;
import net.csdn.business.mirror.entity.bean.ProjectMirrorData;
import net.csdn.business.mirror.enums.UserTokenEnum;
import net.csdn.business.mirror.service.*;
import net.csdn.business.mirror.utils.CsvUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Inner
@RestController()
@RequestMapping("/api/v1/mirror/project")
public class ProjectMirrorController {

    @Autowired
    private ProjectMirrorDataService projectMirrorDataService;

    @Autowired
    private ScheduleTaskService scheduleTaskService;

    @Autowired
    private ProjectMirrorBlackService projectMirrorBlackService;

    @Autowired
    private ImportMirrorConfig importMirrorConfig;

    @Autowired
    private ImportMirrorService importMirrorService;

    @PostMapping(value = "/uploadData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public List<MirrorUploadDto> importData(@RequestParam("file") MultipartFile file) throws Exception {
        InputStream inputStream = null;
        File f = null;
        try {
            f = File.createTempFile("temp" + System.currentTimeMillis(), null);
            file.transferTo(f);
            inputStream = new FileInputStream(f);
            List<String[]> ds = CsvUtil.getData(inputStream);
            List<MirrorUploadDto> result = Lists.newArrayList();
            List<String> repoPaths = Lists.newArrayList();
            List<String> fullPaths = Lists.newArrayList();
            int type = 0;
            if (!CollectionUtils.isEmpty(ds)) {
                String[] arr = ds.get(0);
                String typeStr = arr[3].trim();
                if (StringUtils.isNumeric(typeStr)) {
                    type = Integer.parseInt(typeStr);
                    if (type != 1) {
                        type = 0;
                    }
                }
            }
            UserTokenEnum.Type t = UserTokenEnum.Type.parse(type);
            for (int i = 0; i < ds.size(); i++) {
                String[] arr = ds.get(i);
                if (arr.length < 3) {
                    throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM, "file");
                }
                String repoPath = arr[0].trim();
                String fullPath = arr[1].trim();
                String groupName = fullPath.split("/")[0];
                String groupId = arr[2].trim();
                if (repoPath.split("/").length == 2) {
                    MirrorUploadDto dto = new MirrorUploadDto();
                    dto.setGithubUrl(t.getBaseUrl() + repoPath);
                    dto.setRepoPath(repoPath);
                    dto.setFullPath(fullPath);
                    dto.setMirrorPath(fullPath);
                    dto.setOrgId(groupId);
                    dto.setOrgName(groupName);
                    dto.setMirrorUrl(importMirrorConfig.getMirrorUrl() + dto.getMirrorPath());
                    dto.setType(type);
                    dto.setSource(t.getName());
                    repoPaths.add(dto.getRepoPath());
                    result.add(dto);
                }
                fullPaths.add(fullPath);
            }
            Set<String> existRepoPaths =new HashSet<>();
            Set<String> existFullPaths =new HashSet<>();
            List<String> existBlacks = projectMirrorBlackService.getAllExistsRepoPaths(repoPaths);
            List<ProjectMirrorData> existDataList = projectMirrorDataService.getByFullPaths(fullPaths);
            if(existDataList!=null&&existDataList.size()>0){
                for (ProjectMirrorData data :existDataList){
                    String repoPath = data.getRepoPath();
                    String fullPath = data.getFullPath();
                    existRepoPaths.add(repoPath);
                    existFullPaths.add(fullPath);
                }
            }
            for (MirrorUploadDto dto : result) {
                String repoPath=dto.getRepoPath();
                String fullPath=dto.getFullPath();
                if (existBlacks.contains(repoPath)) {
                    dto.setStatus(2);
                    dto.setStatusDesc("已禁用");
                } else if (existRepoPaths.contains(repoPath)) {
                    dto.setStatus(3);
                    dto.setStatusDesc("已镜像");
                }else if (existFullPaths.contains(fullPath)) {
                    dto.setStatus(4);
                    dto.setStatusDesc("目标path已存在,不可镜像");
                }
            }
            return result;
        } catch (Exception e) {
            log.error("uploadData error", e);
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM, "file");
        } finally {
            f.deleteOnExit();
            inputStream.close();
        }
    }



    @PostMapping("/addData")
    public void addData(@Validated @RequestBody AddMirrorImportDataDTO dto) {
        projectMirrorDataService.batchInsert(dto);
    }

    @PostMapping("/addBlack")
    public void addBlack(@Validated @RequestBody AddMirrorBlackDto addMirrorBlackDto) {
        projectMirrorBlackService.addBlack(addMirrorBlackDto);
    }

    @DeleteMapping("/delBlack")
    public void delBlack(@Validated @RequestBody AddMirrorBlackDto addMirrorBlackDto) {
        projectMirrorBlackService.delBlack(addMirrorBlackDto);
    }

    /**
    * @Description: 管理员分页查询镜像仓库列表
    * @Param:
    * @return:
    * @Author: zhangyl
    * @Date: 2024/7/23
    */
    @PostMapping("/list")
    public Page<ProjectMirrorDataVO> listPageMirror(@Validated @RequestBody MirrorPageQuery query)  {
        return projectMirrorDataService.listPageMirror(query);
    }

    @GetMapping("/getImportSize")
    public long importSize() {
        return projectMirrorDataService.mirrorImportSize();
    }

    
    
    /** 
    * @Description: 修改镜像同步开关
    * @Param: 
    * @return: 
    * @Author: zhangyl
    * @Date: 2024/7/23
    */
    @PutMapping("/syncStatus")
    public Integer changeMirrorSyncStatus(@Validated @RequestBody MirrorSyncStatusDTO params) throws Exception{
       return projectMirrorDataService.changeMirrorSyncStatus(params);
    }

    /**
    * @Description: 镜像删除
    * @Param:
    * @return:
    * @Author: zhangyl
    * @Date: 2024/7/23
    */
    @DeleteMapping
    public Integer deleteMirror(@Validated @RequestBody MirrorDelDTO params)  throws Exception {
        return projectMirrorDataService.deleteMirror(params);
    }

    @PostMapping("/retry")
    public void retry(@Validated @RequestBody MirrorRetyDTO params) throws Exception{
        projectMirrorDataService.retry(params);
    }


    /*
     *管理后台配置数据同步定时任务执行时间和类型
     */
    @PostMapping("/saveGithubSource")
    public void saveGithubSource(@Validated @RequestBody GithubSourceDto sourceDto) {
        scheduleTaskService.saveGithubSource(sourceDto);
    }

    @GetMapping("/getGithubSource")
    public GithubSourceDto getGithubSource() {
        return scheduleTaskService.getGithubSource();
    }

    /**
     * 手动触发镜像仓库导入任务
     */
    @PostMapping("/exec")
    public void exec(@Validated @RequestBody AddMirrorImportDataDTO dto) {
        importMirrorService.exec(dto.getId());
    }

    /**
     * 前台用户启动导入镜像仓库
     */
    @PostMapping("/import")
    public void importProject(@Validated @RequestBody AddMirrorImportDataDTO dto) {
        projectMirrorDataService.startImport(dto);
    }


    /**
     * 前台用户,重试导入镜像仓库
     */
    @PostMapping("/import/retry")
    public void importProjectRetry(@Validated @RequestBody ImportRetryDTO params) {
        projectMirrorDataService.importProjectRetry(params);
    }



    /**
     * 前台用户获取导入仓库列表
     */
    @GetMapping("/user/list")
    public MirrorProjectPageVO getRepoList(@Validated @SpringQueryMap MirrorConfigQuery query) throws Exception {
        return projectMirrorDataService.getRepoList(query);
    }


    /**
     * 前台用户获取源在github或者gittee的全部命名空间
     */
    @GetMapping("/namespace")
    public List<MirrorNameSpaceVO> getNamespace(@Validated @SpringQueryMap MirrorConfigQuery query) throws Exception {
        return projectMirrorDataService.getNamespace(query);
    }


    /**
     * 前台用户获取token信息配置和镜像仓库配置
     */
    @GetMapping("/token")
    public MirrorConfigVO getTokenConfig(@Validated @SpringQueryMap TokenConfigQuery query) {
        return projectMirrorDataService.getTokenConfig(query);
    }


    /**
     * 前台用户更新镜像仓库配置或token信息
     */
    @PostMapping("/token")
    public void updateTokenConfig(@Validated @RequestBody TokenConfigDTO params) throws Exception  {
        projectMirrorDataService.updateTokenConfig(params);
    }

    /**
     * 前台用户获取token信息配置和镜像仓库配置
     */
    @GetMapping("/config")
    public MirrorConfigVO getConfig(@Validated @SpringQueryMap MirrorConfigQuery query) {
        return projectMirrorDataService.getConfig(query);
    }


    /**
     * 前台用户更新镜像仓库配置或token信息
     */
    @PostMapping("/config")
    public void updateConfig(@Validated @RequestBody MirroConfigDTO params) throws Exception  {
        projectMirrorDataService.updateConfig(params);
    }



}